import { Byte } from '../../api/io/Byte';
import { HashMap } from '../../api/struct/HashMap';
import { PlayerInfoSnapshot } from './PlayerInfoSnapshot';
import { PlayerServerSnapshot } from './PlayerServerSnapshot';
import { EquipManagerSnapshot } from './EquipManagerSnapshot';
import { TrainSnapshot } from './TrainSnapshot';
import { PetManagerSnapshot } from './PetManagerSnapshot';
import { TrialTowerSnapshot } from './TrialTowerSnapshot';
import { WorldBossSnapshot } from './WorldBossSnapshot';
import { LegionBossSnapshot } from './LegionBossSnapshot';
import { ArenaSnapshot } from './ArenaSnapshot';
import { LegionSnapshot } from './LegionSnapshot';
import { PlayerTitleSnapshot } from './PlayerTitleSnapshot';
import { ITimer } from '../../api/timer/ITimer';
import { IAsync } from '../../api/event/IAsync';
import { MathUtils } from '../../api/math/MathUtils';



/**角色快照属性枚举*/
export const enum E_PlayerSnapshot {
	/**角色id*/
	PLAYER_ID = 0,
	/**属性<E_GameBaseAttr, 数值>*/
	ATTRIBUTE = 1,
	/**技能<configId, level>*/
	SKILL = 2,
	/**信息*/
	PLAYER_INFO = 3,
	/**服务器信息*/
	SERVER = 4,
	/**装备*/
	EQUIP_MANAGER = 5,
	/**训练*/
	TRAIN = 6,
	/**出战宠物*/
	PET_MANAGER = 7,
	/**试练塔*/
	TRIAL_TOWER = 8,
	/**世界boss*/
	WORLD_BOSS = 9,
	/**军团boss*/
	LEGION_BOSS = 10,
	/**竞技场*/
	ARENA = 11,
	/**军团*/
	LEGION = 12,
	/**称号*/
	TITLE = 13,
	/**枚举数量*/
	EnumCount = 14
}


/**角色快照*/
export class PlayerSnapshot {
	/**事件ID*/
	public static readonly EVENT_ID = 'STRUCT_DATA_PLAYER_SNAPSHOT_EVENT_ID';
	/**整体更新事件ID（部分只需要监听整体变化）*/
	public static readonly TOTAL_EVENT_ID = 'STRUCT_DATA_PLAYER_SNAPSHOT_TOTAL_EVENT_ID';
	/**缓存池*/
	private static POOL: PlayerSnapshot[] = [];

	/**创建入口*/
	public static create(json?: string): PlayerSnapshot {
		const c = this.POOL.pop() || new PlayerSnapshot();
		c._destroyed = false;
		c.resetProperty();
		if (json) {
			c.parse(json);
		}
		return c;
	}


	/**已释放*/
	protected _destroyed = false;
	/**角色id (uint32)*/
	protected _playerId: number;
	/**属性<E_GameBaseAttr, 数值> (uint16, long)*/
	protected _attribute: HashMap<number, number> = null;
	/**技能<configId, level> (uint32, uint16)*/
	protected _skill: HashMap<number, number> = null;
	/**信息*/
	protected _playerInfo: PlayerInfoSnapshot = null;
	/**服务器信息*/
	protected _server: PlayerServerSnapshot = null;
	/**装备*/
	protected _equipManager: EquipManagerSnapshot = null;
	/**训练*/
	protected _train: TrainSnapshot = null;
	/**出战宠物*/
	protected _petManager: PetManagerSnapshot = null;
	/**试练塔*/
	protected _trialTower: TrialTowerSnapshot = null;
	/**世界boss*/
	protected _worldBoss: WorldBossSnapshot = null;
	/**军团boss*/
	protected _legionBoss: LegionBossSnapshot = null;
	/**竞技场*/
	protected _arena: ArenaSnapshot = null;
	/**军团*/
	protected _legion: LegionSnapshot = null;
	/**称号*/
	protected _title: PlayerTitleSnapshot = null;


	/**构建函数-私有，防止外部创建*/
	private constructor() {
	}


	/**释放*/
	public destroy(): void {
		if (this._destroyed) {
			return;
		}
		this._destroyed = true;
		this.resetProperty(true);
		if (PlayerSnapshot.POOL.indexOf(this) === -1) {
			PlayerSnapshot.POOL.push(this);
		}
	}

	/**角色id*/
	public get playerId() {
		return this._playerId;
	}


	/**角色id*/
	public set playerId(v: number) {
		this._playerId = v;
	}


	/**设置属性<E_GameBaseAttr, 数值>*/
	public putAttribute(k: number, v: number): number {
		const ov = this._attribute.put(k, v);
		return ov || 0;
	}


	/**获取属性<E_GameBaseAttr, 数值>*/
	public getAttribute(k: number) {
		return this._attribute.get(k) || 0;
	}


	/**删除属性<E_GameBaseAttr, 数值>*/
	public removeAttribute(k: number): number {
		const ov = this._attribute.remove(k);
		return ov || 0;
	}


	/**获取属性<E_GameBaseAttr, 数值>映射表-键值(外部改变将导致出错，只能用于遍历)*/
	public getAttributeKeys(): number[] {
		return this._attribute.getKeys();
	}


	/**获取属性<E_GameBaseAttr, 数值>映射表-值(外部改变将导致出错，只能用于遍历)*/
	public getAttributeValues(): number[] {
		return this._attribute.getValues();
	}


	/**清空属性<E_GameBaseAttr, 数值>映射表*/
	public clearAttributeMap(): void {
		this._attribute.clear();
	}


	/**设置技能<configId, level>*/
	public putSkill(k: number, v: number): number {
		const ov = this._skill.put(k, v);
		return ov || 0;
	}


	/**获取技能<configId, level>*/
	public getSkill(k: number) {
		return this._skill.get(k) || 0;
	}


	/**删除技能<configId, level>*/
	public removeSkill(k: number): number {
		const ov = this._skill.remove(k);
		return ov || 0;
	}


	/**获取技能<configId, level>映射表-键值(外部改变将导致出错，只能用于遍历)*/
	public getSkillKeys(): number[] {
		return this._skill.getKeys();
	}


	/**获取技能<configId, level>映射表-值(外部改变将导致出错，只能用于遍历)*/
	public getSkillValues(): number[] {
		return this._skill.getValues();
	}


	/**清空技能<configId, level>映射表*/
	public clearSkillMap(): void {
		this._skill.clear();
	}


	/**信息*/
	public get playerInfo() {
		return this._playerInfo;
	}


	/**服务器信息*/
	public get server() {
		return this._server;
	}


	/**装备*/
	public get equipManager() {
		return this._equipManager;
	}


	/**训练*/
	public get train() {
		return this._train;
	}


	/**出战宠物*/
	public get petManager() {
		return this._petManager;
	}


	/**试练塔*/
	public get trialTower() {
		return this._trialTower;
	}


	/**世界boss*/
	public get worldBoss() {
		return this._worldBoss;
	}


	/**军团boss*/
	public get legionBoss() {
		return this._legionBoss;
	}


	/**竞技场*/
	public get arena() {
		return this._arena;
	}


	/**军团*/
	public get legion() {
		return this._legion;
	}


	/**称号*/
	public get title() {
		return this._title;
	}



	/**通过枚举获取值*/
	public getV(k: E_PlayerSnapshot): any {
		switch (k) {
			case E_PlayerSnapshot.PLAYER_ID: return this._playerId;
			case E_PlayerSnapshot.ATTRIBUTE: return this._attribute;
			case E_PlayerSnapshot.SKILL: return this._skill;
			case E_PlayerSnapshot.PLAYER_INFO: return this._playerInfo;
			case E_PlayerSnapshot.SERVER: return this._server;
			case E_PlayerSnapshot.EQUIP_MANAGER: return this._equipManager;
			case E_PlayerSnapshot.TRAIN: return this._train;
			case E_PlayerSnapshot.PET_MANAGER: return this._petManager;
			case E_PlayerSnapshot.TRIAL_TOWER: return this._trialTower;
			case E_PlayerSnapshot.WORLD_BOSS: return this._worldBoss;
			case E_PlayerSnapshot.LEGION_BOSS: return this._legionBoss;
			case E_PlayerSnapshot.ARENA: return this._arena;
			case E_PlayerSnapshot.LEGION: return this._legion;
			case E_PlayerSnapshot.TITLE: return this._title;
			default: return null;
		}
	}


	/**通过枚举设置值*/
	public setV(k: E_PlayerSnapshot, v: any): void {
		switch (k) {
			case E_PlayerSnapshot.PLAYER_ID: this._playerId = v; break;
			case E_PlayerSnapshot.ATTRIBUTE: this._attribute = v; break;
			case E_PlayerSnapshot.SKILL: this._skill = v; break;
			case E_PlayerSnapshot.PLAYER_INFO: this._playerInfo = v; break;
			case E_PlayerSnapshot.SERVER: this._server = v; break;
			case E_PlayerSnapshot.EQUIP_MANAGER: this._equipManager = v; break;
			case E_PlayerSnapshot.TRAIN: this._train = v; break;
			case E_PlayerSnapshot.PET_MANAGER: this._petManager = v; break;
			case E_PlayerSnapshot.TRIAL_TOWER: this._trialTower = v; break;
			case E_PlayerSnapshot.WORLD_BOSS: this._worldBoss = v; break;
			case E_PlayerSnapshot.LEGION_BOSS: this._legionBoss = v; break;
			case E_PlayerSnapshot.ARENA: this._arena = v; break;
			case E_PlayerSnapshot.LEGION: this._legion = v; break;
			case E_PlayerSnapshot.TITLE: this._title = v; break;
			default: break;
		}
	}


	/**初始化*/
	public resetProperty(fromDestroy = false): void {
		//角色id
		this._playerId = 0;
		//属性<E_GameBaseAttr, 数值>
		if (this._attribute) {
			this._attribute.clear();
		}
		else {
			this._attribute = new HashMap<number, number>();
		}
		//技能<configId, level>
		if (this._skill) {
			this._skill.clear();
		}
		else {
			this._skill = new HashMap<number, number>();
		}
		//信息
		if (this._playerInfo) {
			this._playerInfo.destroy();
			this._playerInfo = null;
		}
		if (!fromDestroy) {
			this._playerInfo = PlayerInfoSnapshot.create();
		}
		//服务器信息
		if (this._server) {
			this._server.destroy();
			this._server = null;
		}
		if (!fromDestroy) {
			this._server = PlayerServerSnapshot.create();
		}
		//装备
		if (this._equipManager) {
			this._equipManager.destroy();
			this._equipManager = null;
		}
		if (!fromDestroy) {
			this._equipManager = EquipManagerSnapshot.create();
		}
		//训练
		if (this._train) {
			this._train.destroy();
			this._train = null;
		}
		if (!fromDestroy) {
			this._train = TrainSnapshot.create();
		}
		//出战宠物
		if (this._petManager) {
			this._petManager.destroy();
			this._petManager = null;
		}
		if (!fromDestroy) {
			this._petManager = PetManagerSnapshot.create();
		}
		//试练塔
		if (this._trialTower) {
			this._trialTower.destroy();
			this._trialTower = null;
		}
		if (!fromDestroy) {
			this._trialTower = TrialTowerSnapshot.create();
		}
		//世界boss
		if (this._worldBoss) {
			this._worldBoss.destroy();
			this._worldBoss = null;
		}
		if (!fromDestroy) {
			this._worldBoss = WorldBossSnapshot.create();
		}
		//军团boss
		if (this._legionBoss) {
			this._legionBoss.destroy();
			this._legionBoss = null;
		}
		if (!fromDestroy) {
			this._legionBoss = LegionBossSnapshot.create();
		}
		//竞技场
		if (this._arena) {
			this._arena.destroy();
			this._arena = null;
		}
		if (!fromDestroy) {
			this._arena = ArenaSnapshot.create();
		}
		//军团
		if (this._legion) {
			this._legion.destroy();
			this._legion = null;
		}
		if (!fromDestroy) {
			this._legion = LegionSnapshot.create();
		}
		//称号
		if (this._title) {
			this._title.destroy();
			this._title = null;
		}
		if (!fromDestroy) {
			this._title = PlayerTitleSnapshot.create();
		}
	}


	/**序列化*/
	public stringify(toString: boolean): string | any {
		const json: any = {};
		if (this._playerId) {
			json.playerId = this._playerId;
		}
		if (this._attribute.size() > 0) {
			const ks = this._attribute.getKeys();
			const vs = this._attribute.getValues();
			json.attribute = [ks, vs];
		}
		if (this._skill.size() > 0) {
			const ks = this._skill.getKeys();
			const vs = this._skill.getValues();
			json.skill = [ks, vs];
		}
		if (this._playerInfo) {
			json.playerInfo = this._playerInfo.stringify(false);
		}
		if (this._server) {
			json.server = this._server.stringify(false);
		}
		if (this._equipManager) {
			json.equipManager = this._equipManager.stringify(false);
		}
		if (this._train) {
			json.train = this._train.stringify(false);
		}
		if (this._petManager) {
			json.petManager = this._petManager.stringify(false);
		}
		if (this._trialTower) {
			json.trialTower = this._trialTower.stringify(false);
		}
		if (this._worldBoss) {
			json.worldBoss = this._worldBoss.stringify(false);
		}
		if (this._legionBoss) {
			json.legionBoss = this._legionBoss.stringify(false);
		}
		if (this._arena) {
			json.arena = this._arena.stringify(false);
		}
		if (this._legion) {
			json.legion = this._legion.stringify(false);
		}
		if (this._title) {
			json.title = this._title.stringify(false);
		}

		return toString ? JSON.stringify(json) : json;
	}


	/**反序列化*/
	public parse(jsonv: string | any): this {
		this.resetProperty();
		if (!jsonv) {
			return this;
		}
		const json = typeof (jsonv) === 'string' ? JSON.parse(jsonv) : jsonv;
		if (json.playerId) {
			this._playerId = json.playerId;
		}
		if (json.attribute) {
			const ks: number[] = json.attribute[0];
			const vs: number[] = json.attribute[1];
			if (ks && vs && ks.length === vs.length) {	//json
				this._attribute.setKeyAndValueList(ks, vs);
			}
			else if (json.attribute.getKeys && json.attribute.getValues) {	//结构体
				const ks2 = json.attribute.getKeys();
				const vs2 = json.attribute.getValues();
				if (ks2 && vs2 && ks2.length === vs2.length) {
					for (let i = 0, len = vs2.length; i < len; i++) {
						this._attribute.put(ks2[i], vs2[i]);	//重新添加，防止数据公用后被释放导致bug
					}
				}
			}
		}
		if (json.skill) {
			const ks: number[] = json.skill[0];
			const vs: number[] = json.skill[1];
			if (ks && vs && ks.length === vs.length) {	//json
				this._skill.setKeyAndValueList(ks, vs);
			}
			else if (json.skill.getKeys && json.skill.getValues) {	//结构体
				const ks2 = json.skill.getKeys();
				const vs2 = json.skill.getValues();
				if (ks2 && vs2 && ks2.length === vs2.length) {
					for (let i = 0, len = vs2.length; i < len; i++) {
						this._skill.put(ks2[i], vs2[i]);	//重新添加，防止数据公用后被释放导致bug
					}
				}
			}
		}
		if (json.playerInfo) {
			this._playerInfo.destroy();
			this._playerInfo = PlayerInfoSnapshot.create(json.playerInfo);
		}
		if (json.server) {
			this._server.destroy();
			this._server = PlayerServerSnapshot.create(json.server);
		}
		if (json.equipManager) {
			this._equipManager.destroy();
			this._equipManager = EquipManagerSnapshot.create(json.equipManager);
		}
		if (json.train) {
			this._train.destroy();
			this._train = TrainSnapshot.create(json.train);
		}
		if (json.petManager) {
			this._petManager.destroy();
			this._petManager = PetManagerSnapshot.create(json.petManager);
		}
		if (json.trialTower) {
			this._trialTower.destroy();
			this._trialTower = TrialTowerSnapshot.create(json.trialTower);
		}
		if (json.worldBoss) {
			this._worldBoss.destroy();
			this._worldBoss = WorldBossSnapshot.create(json.worldBoss);
		}
		if (json.legionBoss) {
			this._legionBoss.destroy();
			this._legionBoss = LegionBossSnapshot.create(json.legionBoss);
		}
		if (json.arena) {
			this._arena.destroy();
			this._arena = ArenaSnapshot.create(json.arena);
		}
		if (json.legion) {
			this._legion.destroy();
			this._legion = LegionSnapshot.create(json.legion);
		}
		if (json.title) {
			this._title.destroy();
			this._title = PlayerTitleSnapshot.create(json.title);
		}
		return this;
	}


	/**序列化-二进制*/
	public toBytes(byte: Byte): void {
		if (!byte) {
			return;
		}
		byte.writeUint32(this._playerId);
		//属性<E_GameBaseAttr, 数值>
		{
			const ks = this._attribute.getKeys();
			const vs = this._attribute.getValues();
			const len = ks.length;
			byte.writeUint16(len);
			for (let i = 0; i < len; i++) {
				byte.writeUint16(ks[i]);
				byte.writeLongNumber(vs[i]);
			}
		}
		//技能<configId, level>
		{
			const ks = this._skill.getKeys();
			const vs = this._skill.getValues();
			const len = ks.length;
			byte.writeUint16(len);
			for (let i = 0; i < len; i++) {
				byte.writeUint32(ks[i]);
				byte.writeUint16(vs[i]);
			}
		}
		this._playerInfo.toBytes(byte);
		this._server.toBytes(byte);
		this._equipManager.toBytes(byte);
		this._train.toBytes(byte);
		this._petManager.toBytes(byte);
		this._trialTower.toBytes(byte);
		this._worldBoss.toBytes(byte);
		this._legionBoss.toBytes(byte);
		this._arena.toBytes(byte);
		this._legion.toBytes(byte);
		this._title.toBytes(byte);
	}


	/**反序列化-二进制*/
	public fromBytes(byte: Byte): this {
		this.resetProperty();
		if (!byte) {
			return;
		}
		this._playerId = byte.readUint32();
		//属性<E_GameBaseAttr, 数值>
		{
			const len = byte.readUint16();
			for (let i = 0; i < len; i++) {
				const k = byte.readUint16();
				const v = byte.readLongNumber();
				this._attribute.put(k, v);
			}
		}
		//技能<configId, level>
		{
			const len = byte.readUint16();
			for (let i = 0; i < len; i++) {
				const k = byte.readUint32();
				const v = byte.readUint16();
				this._skill.put(k, v);
			}
		}
		this._playerInfo.fromBytes(byte);
		this._server.fromBytes(byte);
		this._equipManager.fromBytes(byte);
		this._train.fromBytes(byte);
		this._petManager.fromBytes(byte);
		this._trialTower.fromBytes(byte);
		this._worldBoss.fromBytes(byte);
		this._legionBoss.fromBytes(byte);
		this._arena.fromBytes(byte);
		this._legion.fromBytes(byte);
		this._title.fromBytes(byte);
		return this;
	}


	/**克隆*/
	public clone(): PlayerSnapshot {
		const byte = Byte.createFromPool();
		this.toBytes(byte);
		byte.pos = 0;
		const clonev = PlayerSnapshot.create().fromBytes(byte);
		Byte.recoverToPool(byte);
		return clonev;
	}


	/**处理更新*/
	public processUpdate(jsonv: string): void {
		if (!jsonv) {
			return;
		}

		const eventID = PlayerSnapshot.EVENT_ID;
		const us = JSON.parse(jsonv);

		for (let i = 0, len = us.length; i < len;) {
			const idx = us[i];
			//角色id
			if (idx === E_PlayerSnapshot.PLAYER_ID) {
				const oldv = this._playerId;
				this._playerId = us[i + 1];
				IAsync.dispatch(eventID, idx, this._playerId, oldv);
				i += 2;
				continue;
			}

			//属性<E_GameBaseAttr, 数值>
			if (idx === E_PlayerSnapshot.ATTRIBUTE) {
				const k: number = us[i + 1];
				const newv :number = us[i + 2];
				const oldv = this.putAttribute(k, newv);
				IAsync.dispatch(eventID, idx, k, newv, oldv);
				i += 3;
				continue;
			}

			//技能<configId, level>
			if (idx === E_PlayerSnapshot.SKILL) {
				const k: number = us[i + 1];
				const newv :number = us[i + 2];
				const oldv = this.putSkill(k, newv);
				IAsync.dispatch(eventID, idx, k, newv, oldv);
				i += 3;
				continue;
			}
			//信息
			if (idx === E_PlayerSnapshot.PLAYER_INFO) {
				const fui: string = us[i + 1];
				if (this._playerInfo) {
					this._playerInfo.processUpdate(fui);
				}
				else {
					console.error('PlayerSnapshot playerInfo is null when update.');
				}
				IAsync.dispatch(eventID, idx);
				i += 2;
				continue;
			}
			//服务器信息
			if (idx === E_PlayerSnapshot.SERVER) {
				const fui: string = us[i + 1];
				if (this._server) {
					this._server.processUpdate(fui);
				}
				else {
					console.error('PlayerSnapshot server is null when update.');
				}
				IAsync.dispatch(eventID, idx);
				i += 2;
				continue;
			}
			//装备
			if (idx === E_PlayerSnapshot.EQUIP_MANAGER) {
				const fui: string = us[i + 1];
				if (this._equipManager) {
					this._equipManager.processUpdate(fui);
				}
				else {
					console.error('PlayerSnapshot equipManager is null when update.');
				}
				IAsync.dispatch(eventID, idx);
				i += 2;
				continue;
			}
			//训练
			if (idx === E_PlayerSnapshot.TRAIN) {
				const fui: string = us[i + 1];
				if (this._train) {
					this._train.processUpdate(fui);
				}
				else {
					console.error('PlayerSnapshot train is null when update.');
				}
				IAsync.dispatch(eventID, idx);
				i += 2;
				continue;
			}
			//出战宠物
			if (idx === E_PlayerSnapshot.PET_MANAGER) {
				const fui: string = us[i + 1];
				if (this._petManager) {
					this._petManager.processUpdate(fui);
				}
				else {
					console.error('PlayerSnapshot petManager is null when update.');
				}
				IAsync.dispatch(eventID, idx);
				i += 2;
				continue;
			}
			//试练塔
			if (idx === E_PlayerSnapshot.TRIAL_TOWER) {
				const fui: string = us[i + 1];
				if (this._trialTower) {
					this._trialTower.processUpdate(fui);
				}
				else {
					console.error('PlayerSnapshot trialTower is null when update.');
				}
				IAsync.dispatch(eventID, idx);
				i += 2;
				continue;
			}
			//世界boss
			if (idx === E_PlayerSnapshot.WORLD_BOSS) {
				const fui: string = us[i + 1];
				if (this._worldBoss) {
					this._worldBoss.processUpdate(fui);
				}
				else {
					console.error('PlayerSnapshot worldBoss is null when update.');
				}
				IAsync.dispatch(eventID, idx);
				i += 2;
				continue;
			}
			//军团boss
			if (idx === E_PlayerSnapshot.LEGION_BOSS) {
				const fui: string = us[i + 1];
				if (this._legionBoss) {
					this._legionBoss.processUpdate(fui);
				}
				else {
					console.error('PlayerSnapshot legionBoss is null when update.');
				}
				IAsync.dispatch(eventID, idx);
				i += 2;
				continue;
			}
			//竞技场
			if (idx === E_PlayerSnapshot.ARENA) {
				const fui: string = us[i + 1];
				if (this._arena) {
					this._arena.processUpdate(fui);
				}
				else {
					console.error('PlayerSnapshot arena is null when update.');
				}
				IAsync.dispatch(eventID, idx);
				i += 2;
				continue;
			}
			//军团
			if (idx === E_PlayerSnapshot.LEGION) {
				const fui: string = us[i + 1];
				if (this._legion) {
					this._legion.processUpdate(fui);
				}
				else {
					console.error('PlayerSnapshot legion is null when update.');
				}
				IAsync.dispatch(eventID, idx);
				i += 2;
				continue;
			}
			//称号
			if (idx === E_PlayerSnapshot.TITLE) {
				const fui: string = us[i + 1];
				if (this._title) {
					this._title.processUpdate(fui);
				}
				else {
					console.error('PlayerSnapshot title is null when update.');
				}
				IAsync.dispatch(eventID, idx);
				i += 2;
				continue;
			}

			console.error('[Struct Data] can not find enum in PlayerSnapshot with idx = ' + idx + ', version maybe wrong.')
		}

		//全更事件
		ITimer.callLater(this, this.dispatchTotalUpdate);
	}


	/**比对不一致结果*/
	public getCompareInfo(other: PlayerSnapshot): string {
		if (!other) {
			return null;
		}

		const updates: any[] = [];

		if (this._playerId !== other._playerId) {
			updates.push(E_PlayerSnapshot.PLAYER_ID, this._playerId);
		}

		//属性<E_GameBaseAttr, 数值>
		{
			const idx = E_PlayerSnapshot.ATTRIBUTE;
			const ks1 = this._attribute.getKeys();
			const ks2 = other._attribute.getKeys();
			const vs1 = this._attribute.getValues();
			const vs2 = other._attribute.getValues();
			const rs = MathUtils.intersectSortedArray(ks1, ks2, vs1, vs2);
			if (rs[0].length > 0) {
				const list = rs[0];
				for (let i = 0, len = list.length; i < len; i++) {
					const k = list[i];
					const newv = this.getAttribute(k);
					updates.push(idx, k, newv);
				}
			}
			if (rs[1].length > 0) {
				const list = rs[1];
				for (let i = 0, len = list.length; i < len; i++) {
					const k = list[i];
					const newv = this.getAttribute(k);
					updates.push(idx, k, newv);
				}
			}
			if (rs[2].length > 0) {
				const list = rs[2];
				for (let i = 0, len = list.length; i < len; i++) {
					updates.push(idx, list[i], 0);
				}
			}
		}

		//技能<configId, level>
		{
			const idx = E_PlayerSnapshot.SKILL;
			const ks1 = this._skill.getKeys();
			const ks2 = other._skill.getKeys();
			const vs1 = this._skill.getValues();
			const vs2 = other._skill.getValues();
			const rs = MathUtils.intersectSortedArray(ks1, ks2, vs1, vs2);
			if (rs[0].length > 0) {
				const list = rs[0];
				for (let i = 0, len = list.length; i < len; i++) {
					const k = list[i];
					const newv = this.getSkill(k);
					updates.push(idx, k, newv);
				}
			}
			if (rs[1].length > 0) {
				const list = rs[1];
				for (let i = 0, len = list.length; i < len; i++) {
					const k = list[i];
					const newv = this.getSkill(k);
					updates.push(idx, k, newv);
				}
			}
			if (rs[2].length > 0) {
				const list = rs[2];
				for (let i = 0, len = list.length; i < len; i++) {
					updates.push(idx, list[i], 0);
				}
			}
		}
		//信息
		{
			const ui = this._playerInfo.getCompareInfo(other._playerInfo);
			if (ui && ui.length > 0) {
				updates.push(E_PlayerSnapshot.PLAYER_INFO, ui);
			}
		}
		//服务器信息
		{
			const ui = this._server.getCompareInfo(other._server);
			if (ui && ui.length > 0) {
				updates.push(E_PlayerSnapshot.SERVER, ui);
			}
		}
		//装备
		{
			const ui = this._equipManager.getCompareInfo(other._equipManager);
			if (ui && ui.length > 0) {
				updates.push(E_PlayerSnapshot.EQUIP_MANAGER, ui);
			}
		}
		//训练
		{
			const ui = this._train.getCompareInfo(other._train);
			if (ui && ui.length > 0) {
				updates.push(E_PlayerSnapshot.TRAIN, ui);
			}
		}
		//出战宠物
		{
			const ui = this._petManager.getCompareInfo(other._petManager);
			if (ui && ui.length > 0) {
				updates.push(E_PlayerSnapshot.PET_MANAGER, ui);
			}
		}
		//试练塔
		{
			const ui = this._trialTower.getCompareInfo(other._trialTower);
			if (ui && ui.length > 0) {
				updates.push(E_PlayerSnapshot.TRIAL_TOWER, ui);
			}
		}
		//世界boss
		{
			const ui = this._worldBoss.getCompareInfo(other._worldBoss);
			if (ui && ui.length > 0) {
				updates.push(E_PlayerSnapshot.WORLD_BOSS, ui);
			}
		}
		//军团boss
		{
			const ui = this._legionBoss.getCompareInfo(other._legionBoss);
			if (ui && ui.length > 0) {
				updates.push(E_PlayerSnapshot.LEGION_BOSS, ui);
			}
		}
		//竞技场
		{
			const ui = this._arena.getCompareInfo(other._arena);
			if (ui && ui.length > 0) {
				updates.push(E_PlayerSnapshot.ARENA, ui);
			}
		}
		//军团
		{
			const ui = this._legion.getCompareInfo(other._legion);
			if (ui && ui.length > 0) {
				updates.push(E_PlayerSnapshot.LEGION, ui);
			}
		}
		//称号
		{
			const ui = this._title.getCompareInfo(other._title);
			if (ui && ui.length > 0) {
				updates.push(E_PlayerSnapshot.TITLE, ui);
			}
		}

		const jsonv = updates.length === 0 ? null : JSON.stringify(updates);
		return jsonv;
	}


	/**全部更新*/
	protected dispatchTotalUpdate(): void {
		IAsync.dispatch(PlayerSnapshot.TOTAL_EVENT_ID, this.getV(0));
	}

}
